package fr.ensai.lignededix.controleur;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.StringTokenizer;
import fr.ensai.lignededix.bd.DAO;
import fr.ensai.lignededix.bd.DAOFactory;
import fr.ensai.lignededix.exceptions.FonctionalException;
import fr.ensai.lignededix.exceptions.TechnicalException;
import fr.ensai.lignededix.menu.Menu;
import fr.ensai.lignededix.menu.Menu.Action;
import fr.ensai.lignededix.metier.jeton.Jeton;
import fr.ensai.lignededix.metier.jeton.Simple;
import fr.ensai.lignededix.metier.joueur.Joueur;
import fr.ensai.lignededix.metier.joueur.Utilisateur;
import fr.ensai.lignededix.metier.partie.Case;
import fr.ensai.lignededix.metier.partie.Partie;


public class ControleurMenu {


	public static final int TAILLE_GRILLE_MIN=6, TAILLE_GRILLE_MAX=12;
	private static Utilisateur utilisateur1;
	private static Utilisateur utilisateur2;
	private static Menu menuConnexion,menuChoixDuTypeDePartie, menuGeneral,  menuChoixDuNiveauDeJeu,menuReseau;
	private static List<Utilisateur> listeAttente;
	private static Action actionEnCours;
	private static Action actionSuivante;



	public ControleurMenu(){
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		////////////////////////////                                                              ////////////////////////////////////
		////////////////////////////               INITIALISATION   DES   VARIABLES               ////////////////////////////////////
		////////////////////////////                                                              ////////////////////////////////////
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


		actionEnCours=Action.menuConnexion; // le programme commence par l'etape connexion


		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////                                                                /////////////////////////////////////
		/////////////////////////                         CREATION  DES  MENUS                   /////////////////////////////////////
		/////////////////////////                                                                /////////////////////////////////////
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		// Création du   MENU  CHOIX DU NIVEAU DE JEU
		String listeChoixMenuChoixDuNiveauDeJeu[][]={
				{"","1","niveau0"},
				{"","2","niveau1"},
				{"","3","niveau2"}};	
		menuChoixDuNiveauDeJeu=new Menu("Veuillez taper votre niveau de jeu 1, 2 ou 3.",listeChoixMenuChoixDuNiveauDeJeu);	

		// Création du   MENU  CHOIX DU TYPE DE PARTIE
		String listeChoixMenuChoixDuTypeDePartie[][]={
				{"Si vous voulez débuter une Nouvelle partie tapez N.","N","debuterUneNouvellePartie"},
				{"Si vous voulez reprendre une Ancienne partie tapez A.","A","reprendreUneAnciennePartie"}};
		menuChoixDuTypeDePartie=new Menu("",listeChoixMenuChoixDuTypeDePartie);

		// Création du   MENU  CONNEXION
		String listeChoixMenuConnexion[][]={
				{"Si vous voulez vous Authentifier tapez A.","A","authentification"},
				{"Si vous voulez créer un Compte tapez C.","C","afficherReglesJeuMenuInscription"},
				{"Si vous voulez Quitter tapez Q.","Q","quitterProgramme"}};	
		menuConnexion=new Menu(" Bienvenue ! ",listeChoixMenuConnexion);	

		//Création du MENU RESEAU
		String listeChoixMenuReseau[][]={
				{"Si vous voulez vous inscrire sur la liste d'attente tapez I.","I","inscrireListeAttente"},
				{"Si vous voulez choisir un adversaire tapez C.","C","choisirAdversaire"},
				{"Si vous voulez retourner au menu général tapez G.","G","menuGeneral"}};	
		menuReseau=new Menu("",listeChoixMenuReseau);

		// création du   MENU  GENERAL
		String listeChoixMenuGeneral[][]={
				{"Si vous voulez Jouer avec un autre joueur sur cet ordinateur tapez J.","J","jouerUnePartieContreUnJoueur"},
				{"Si vous voulez jouer une Partie en réseau tapez P.","P","jouerUnePartieEnReseau"},
				{"Si vous voulez jouer une partie contre l'Ordinateur tapez O.","O","jouerUnePartieContreOrdinateur"},			
				{"Si vous voulez consulter les Statistiques tapez S.","S","consulterStatistique"},
				{"Si vous voulez consulter les Règles du jeu tapez R.","R","afficherReglesJeuMenuGeneral"},
				{"Si vous voulez Quitter tapez Q.","Q","quitterProgramme"}};
		menuGeneral=new Menu("Menu général : ",listeChoixMenuGeneral);








		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/////////////////                                                                                                                  ////////////////
		/////////////////                   P A R T I E      P R I N C I P A L E    D U     P R O G R A M M E                              ////////////////		
		/////////////////                                                                                                                  ////////////////		
		/////////////////------------------------------------------------------------------------------------------------------------------////////////////
		/////////////////                                                                                                                  ////////////////
		/////////////////            on passe d'une action à une autre tant que l'utilisateur ne choisi pas de quitter l'application       ////////////////
		/////////////////            la variable String  actionEnCours	  permet de savoir quelle phase du programme doit etre executee    ////////////////
		/////////////////            la boucle while s'execute tant que actionEnCours n'est pas egal a "quitterProgramme"	               ////////////////
		/////////////////                                                                                                                  ////////////////
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////		

		while(!(actionEnCours.equals(Action.quitterProgramme))){  //les actions se succèdent tant que l'utilisateur ne choisit pas de quitter l'application


			switch(actionEnCours){


			case afficherReglesJeuMenuInscription :  //affichage des regles du jeu puis lancement du menu inscription
				actionEnCours=Action.menuInscription;			
				break;	


			case afficherReglesJeuMenuGeneral:  //affichage des règles du jeu puis lancement du menu general
				afficherReglesDuJeu();
				actionEnCours=Action.menuGeneral;
				break;		


			case authentifierJoueur :
				try{
					actionEnCours=authentifierJoueur(1);
				}
				catch (FonctionalException fe) {
					actionEnCours=Action.menuConnexion;
				}
				catch (TechnicalException fe){
					actionEnCours=Action.quitterProgramme;
				}
				break;



			case choisirAdversaire :
				choisirAdversaire();
				break;


			case consulterStatistique :
				DAO<Utilisateur> ud1=DAOFactory.getUtilisateurDAO();
				try {
					System.out.println(ud1.calculerDesStatistiques(utilisateur1));
				} catch (FonctionalException e2) {


				}
				actionEnCours=Action.menuGeneral; 
				break;


			case inscrireListeAttente :			
				inscrireListeAttente();
				actionEnCours=Action.menuGeneral;
				break;


			case jouerUnePartieContreUnJoueur :

				try{
					gererMenuConnexionJoueur2();

					if (actionEnCours!=Action.quitterProgramme){ //ici commence une partie entre deux joueurs

						choisirNouvelleOuReprendrePartie();
						actionEnCours=Action.menuGeneral; 
					}

					break;

				}catch (FonctionalException e) {
					actionEnCours=Action.menuGeneral;
				}
				catch (TechnicalException te) {
					actionEnCours=Action.quitterProgramme;
				}

			case jouerUnePartieContreOrdinateur :

				choisirNiveauDeDifficulteIA();
				choisirNouvelleOuReprendrePartie();

				actionEnCours=Action.menuGeneral;
				break; 

			case jouerUnePartieEnReseau :

				try {

					listeAttente=afficherListeAttente(utilisateur1);	
					menuReseau.afficheMenu();
					actionEnCours=menuReseau.obtenirChoixUtilisateur();


				} catch (FonctionalException e1) {
					actionEnCours=Action.menuGeneral;
				}
				break; 


			case menuConnexion :
				menuConnexion.afficheMenu();
				actionEnCours=menuConnexion.obtenirChoixUtilisateur();
				break;


			case menuGeneral : 
				System.out.println();
				System.out.println();
				menuGeneral.afficheMenu(); 
				actionEnCours=menuGeneral.obtenirChoixUtilisateur();
				break;


			case menuInscription :

				try {
					gererInscription(1);              //execution du menu incription
					actionEnCours=Action.menuGeneral;

				} catch (FonctionalException e) {
					actionEnCours=Action.menuConnexion;
				}
				catch (TechnicalException e) {
					actionEnCours=Action.quitterProgramme;
				}

				break;






			}
		}
		System.out.println();
		System.out.println();
		try {
			DAOFactory.endConnection();
		} catch (TechnicalException te) {


		}
		System.out.println("Vous avez choisi d'arrêter le programme.");
		System.out.println();
		System.out.println("A bientôt.");

	}


	/**méthode permettant d'afficher les règles du jeu
	 */

	public static void afficherReglesDuJeu(){

		System.out.println("a) Principe général du jeu :");
		System.out.println("--------------------------------");
		System.out.println("Ligne de dix se joue à deux sur une grille carrée de taille n (avec n entier compris entre 6 et");
		System.out.println("12 (inclus)). Les participants jouent chacun leur tour.");
		System.out.println("Un coup consiste soit à placer un de ses jetons sur la grille de jeu, soit à déplacer un de ses");
		System.out.println("jetons déjà présent sur la grille.");
		System.out.println("En début de partie, toutes les cases de la grille sont vides. En cours de partie, chaque case de");
		System.out.println("la grille de jeu est vide ou contient un jeton(une case ne peut pas contenir plusieurs jetons).");
		System.out.println("En fin de partie, la grille est pleine");
		System.out.println(" ");
		System.out.println("b) Préparation de la partie :");	
		System.out.println("-----------------------------");
		System.out.println("Le joueur qui débute est désigné aléatoirement. Ce joueur aura les jetons blancs, l’autre aura");
		System.out.println("les jetons noirs.");
		System.out.println("Les joueurs se mettent d’accord sur la taille n de la grille (avec n entier compris entre 6 et ");
		System.out.println("12 (inclus)),sur laquelle ils vont jouer (cette grille est un carré composé de n cases par n cases).");
		System.out.println(" ");
		System.out.println("c) Début de la partie :");
		System.out.println("-----------------------");
		System.out.println("En début de partie, chaque joueur dispose de jetons de sa couleur (blancs ou noirs) :");
		System.out.println("	deux jetons « Multi »");
		System.out.println("	deux jetons « Joker »");
		System.out.println("	deux jetons « Diable »");
		System.out.println("	autant de jetons « Simple » qu’il veut.");
		System.out.println("Tous les jetons (qu’ils soient de type « Simple », « Multi », « Joker » ou « Diable ») ont une");
		System.out.println("valeur.");
		System.out.println("Cette valeur est un entier compris entre 1 et 7 (inclus) qui est choisi librement par le joueur");
		System.out.println("au moment où il pose son jeton sur la grille.");
		System.out.println("Les jetons d’un même joueur n’ont donc pas forcément la même valeur et celle-ci se décide");
		System.out.println("seulement au moment où le joueur pose son jeton sur la grille de jeu.");
		System.out.println("En début de partie, toutes les cases de la grille de jeu sont vides.");
		System.out.println("La partie commence lorsque le joueur qui a les jetons blancs pose un de ses jetons sur une case");
		System.out.println("de la grille de jeu et lui affecte une valeur.");
		System.out.println("C’est ensuite au joueur qui a les jetons noirs de faire de même.");
		System.out.println("Les deux adversaires jouent ainsi alternativement un coup, comme expliqué ci-dessous.");
		System.out.println(" ");
		System.out.println("d) Tour d’un joueur :");
		System.out.println("---------------------");
		System.out.println("Tout au long de la partie, les participants jouent chacun leur tour.");
		System.out.println("Lorsque c’est le tour d’un joueur il peut au choix effectuer l’une des quatre actions suivantes :");
		System.out.println(" - poser l’un de ses jetons (non encore utilisé) sur une case vide de la grille de jeu");
		System.out.println(" - si lors d’un coup antérieur le joueur a déjà posé un de ses jeton « Joker » sur une case,");
		System.out.println("   il peut le déplacer sur une case adjacente vide.");
		System.out.println("   Chaque jeton « Joker » ne peut être déplacé qu’une seule fois au cours d’une partie.");
		System.out.println(" - si lors d’un coup antérieur le joueur a déjà posé un de ses jeton « Diable » sur une case, il");
		System.out.println(";peut le déplacer sur une case adjacente vide ou occupée par un jeton adverse.");
		System.out.println("   Si l’on déplace un jeton « Diable » sur une case déjà occupée par un jeton adverse, ce dernier");
		System.out.println("   est définitivement retiré du jeu.");
		System.out.println("   Chaque jeton « Diable » ne peut être déplacé qu’une seule fois au cours d’une partie.");
		System.out.println(" - passer son tour : cependant cette action est possible uniquement en fin de partie et dans les");
		System.out.println("conditions exposées dans le paragraphe f) Fin de la partie.");
		System.out.println(" ");
		System.out.println("e) Décompte des points :");
		System.out.println("------------------------");
		System.out.println("On appelle « ligne de dix », trois cases consécutives qui comportent des jetons d’une même");
		System.out.println("couleur, et dont la somme des valeurs est égale à dix.");
		System.out.println("Une « ligne de dix » peut être horizontale, verticale, diagonale ascendante, ou diagonale");
		System.out.println("descendante.");
		System.out.println("Ce jeu consiste à former le maximum de « lignes de dix ».");
		System.out.println("Chaque « ligne de dix » apporte un point au joueur si cette « ligne de dix » ne comporte pas de");
		System.out.println("jeton « Multi », deux points si cette « ligne de dix » comporte un jeton « Multi », et quatre ");
		System.out.println("points si cette « ligne de dix » comporte deux jetons « Multi ».");
		System.out.println("Le score d’un joueur est égal au maximum de points que l’on peut compter sur la grille en");
		System.out.println("respectant la règle suivante :");
		System.out.println("un jeton peut être utilisé pour plusieurs « lignes de dix » mais seulement une fois");
		System.out.println("dans chacune des directions (horizontale, verticale, diagonale ascendante, diagonale descendante).");
		System.out.println(" ");
		System.out.println("f) Fin de la partie :");
		System.out.println("---------------------");
		System.out.println("Lorsque toutes les cases de la grille de jeu sont remplies les joueurs peuvent choisir de passer");
		System.out.println("leur tour ou d’utiliser un de leurs diables (non encore utilisé).");
		System.out.println("Si les deux joueurs souhaitent passer leur tour, la partie s’achève.");
		System.out.println("Si l’un des joueurs dont c’est le tour choisit de bouger son diable, la partie se prolonge");
		System.out.println("jusqu’à ce que tous les diables aient été bougés ou jusqu’à ce que les joueurs aient décidé");
		System.out.println("conjointement d’arrêter la partie.");
		System.out.println("Exemple : Le Joueur 1 décide de passer son tour alors que la grille vient juste d’être remplie");
		System.out.println("entièrement.");
		System.out.println("Le Joueur 2 a alors le choix de passer son tour ou de bouger un diable.");
		System.out.println("S’il choisit de passer son tour, la partie s’achève.");
		System.out.println("Sinon, le Joueur 1 a de nouveau la possibilité de choisir une action.");
		System.out.println("Et ainsi de suite jusqu’à ce que les joueurs décident successivement de passer leur tour, ce qui");
		System.out.println("marque la fin de la partie.");
		System.out.println(" ");
		System.out.println("A la fin d’une partie on fait le décompte des points (comme expliqué en 5) ).");
		System.out.println("Si l’un des joueurs a plus de points que l’autre il est déclaré gagnant de la partie, sinon les");
		System.out.println("deux joueurs sont à égalité.");
		System.out.println("");
		System.out.println("");
		System.out.println("==============================================================================================");
		System.out.println("");
		System.out.println("");

	}



	/**
	 * méthode qui permet de gérer l'inscription (la création d'un compte) d'un utilisateur 
	 * la méthode boucle tant que l'utilisateur ne donne pas un nom non encore utilisé entre 3 et 12 caractère
	 * ensuite la méthode passe à la phase choix d'un mot de passe : l'utilisateur doit taper un mot de passe
	 * puis retaper ce dernier à titre de vérification : la méthode boucle tant que l'utilisateur n'a pas donné
	 * un mot de passe valide (entre 4 et 12 carcatères) ou s'il ne tape pas deux fois de suite le même
	 * mot de passe
	 * @param numeroUtilisateur : entier qui peut prendre la valeur 1 ou 2 suivant que l'utilisateur a authentifier soit l'utilisateur 1 ou 2
	 * @throws FonctionalException
	 * @throws TechnicalException
	 */
	public static void gererInscription(int numeroUtilisateur) throws FonctionalException,TechnicalException{
		System.out.println("Choisissez un nom de 3 caractères au minimum et de 12 caractères au maximum.");

		boolean choixNomValide=false, motDePasseValide=false, motsDePasseIdentiques=false;
		String choixNom=null, choixMotDePasse, verifMotDePasse;


		while(!choixNomValide){  //boucle tant que l'utilisateur n'a pas choisi un nom valide
			Scanner scNom=new Scanner(System.in);
			choixNom=(scNom.nextLine()).toUpperCase();

			if (choixNom.length()<3){
				System.out.println("Ce nom est trop court (il doit avoir 3 caractères au minimum), réessayez.");
			}
			else {  //cas ou le nom choisi a au moins 3 caracteres
				if (choixNom.length()>12) {
					System.out.println("Ce nom est trop long (il doit avoir 12 caractères au maximum), réessayez.");
				}	
				else{  //cas ou le nom choisi a entre 3 et 12 caracteres


					DAO<Utilisateur> ud1=DAOFactory.getUtilisateurDAO();
					if (!ud1.isPseudoValide(choixNom)) //On consulte la base de donnee
					{  //cas ou le pseudo est deja pris
						System.out.println("Ce nom est déjà pris, réessayez."); 
					}

					else {  //cas ou le pseudo n est pas encore pris
						System.out.println("Ce nom n'est pas encore pris.");
						choixNomValide=true;
					}
				}
			}
		}

		//maintenant le nom choisi a le bon nombre de caracteres et n'est pas encore pris

		if (!(choixNom).equals("G")) {
			while(!motDePasseValide){  
				System.out.println("Saisissez un mot de passe de 4 caractères au minimum et 12 au maximum.");
				Scanner scMotDePasse=new Scanner(System.in);						
				choixMotDePasse=scMotDePasse.nextLine();
				System.out.println("A titre de vérification, veuillez retaper votre mot de passe.");
				Scanner scVerifMotDePasse=new Scanner(System.in);
				verifMotDePasse=scVerifMotDePasse.nextLine();
				motsDePasseIdentiques=choixMotDePasse.equals(verifMotDePasse);


				if (!motsDePasseIdentiques){  //cas ou les deux mots de passe tapes sont differents
					System.out.println("Le mot de passe que vous avez tapé en premier n'est pas identique à celui que vous avez tapé en second, veuillez recommencer.");
				}

				else{  //cas ou les deux mots de passe tapes sont identiques
					if (choixMotDePasse.length()<4){  //cas ou le mot de passe est trop court
						System.out.println("Ce mot de passe est trop court (il doit avoir 4 caractères au minimum), réessayez.");
					}
					else {  //cas ou le mot de passe n'est pas trop court
						if (choixMotDePasse.length()>12) {  //cas ou le mot de passe est trop long
							System.out.println("Ce mot de passe est trop long (il doit avoir 12 caractères au maximum), réessayez.");
						}
						else {  //cas ou les deux mots de passe sont identiques et ont le bon nombre de caracteres
							int dernierUtilisateurCree=-1;

							if (numeroUtilisateur==1) {
								DAO<Utilisateur> ud1=DAOFactory.getUtilisateurDAO();
								Utilisateur user1=new Utilisateur(choixNom, choixMotDePasse);
								dernierUtilisateurCree=ud1.create(user1);
								utilisateur1=user1;
								utilisateur1.setNumUtilisateur(dernierUtilisateurCree);

							}
							else {
								DAO<Utilisateur> ud1=DAOFactory.getUtilisateurDAO();
								Utilisateur user2=new Utilisateur(choixNom, choixMotDePasse);
								dernierUtilisateurCree=ud1.create(user2);
								utilisateur2=user2;
								utilisateur2.setNumUtilisateur(dernierUtilisateurCree);

							}


							//create renvoie un entier egal a l'identifiant du dernier utilisateur
							//ajoute dans la base de donnees, il renvoie 0
							if (dernierUtilisateurCree!=-1) {
								motDePasseValide=true;
							}

						}						
					}
				}
			}
		}
		// l'utilisateur a choisi un nom et un mot de passe valide, son compte utilisateur est créé, il est renvoyé au menu général
	}



	///////////////////////////////////////////////////////////////////////////////////////////////
	/////                     METHODE QUI GERE L'AUTHENTIFICATION                             /////
	///////////////////////////////////////////////////////////////////////////////////////////////


	/**
	 * méthode qui permet de gérer l'authentification d'un utilisateur 
	 * la méthode demande à l'utilisateur de taper son pseudonyme, puis son mot de passe 
	 * si l'utilisateur tape un pseudonyme qui n'existe pas encore, ou ne tape pas le mot de passe associé la méthode
	 * 		si l'authentification est réussie : l'application la méthode le dis à l'utilisateur et on sort de la méthode
	 *  	si l'authentification n'est pas réussie : l'application renvoie l'utilisateur au menu connexion
	 * @param numeroUtilisateur : entier qui peut prendre la valeur ou 2 suivant que l'utilisateur a authentifier soit l'utilisateur 1 ou 2
	 * @return une action
	 * @throws FonctionalException
	 * @throws TechnicalException
	 */

	public static Action authentifierJoueur(int numeroUtilisateur) throws FonctionalException, TechnicalException{
		int authentificationReussie=-1;  
		Action actionSuivante = null;

		System.out.println("Entrez votre pseudonyme.");
		Scanner sc=new Scanner(System.in);
		String pseudoTape;
		pseudoTape=(sc.nextLine().toUpperCase());
		System.out.println("Entrez votre mot de passe.");
		Scanner sc1=new Scanner(System.in);
		String motDePasseTape;
		motDePasseTape=sc1.nextLine();

		//DAO

		DAO<Utilisateur> ud1=DAOFactory.getUtilisateurDAO();
		authentificationReussie=ud1.authentifier(pseudoTape, motDePasseTape);

		if (authentificationReussie!=-1){       //si l'utilisateur a tape un nom est valide et le mot de passe associe il accede au menu general
			if (numeroUtilisateur==1) {
				utilisateur1=new Utilisateur(authentificationReussie,pseudoTape,motDePasseTape);

				System.out.println("Bravo, authentification réussie.");	
				actionSuivante=Action.menuGeneral;
			}
			else if(numeroUtilisateur==2){
				utilisateur2=new Utilisateur(authentificationReussie,pseudoTape,motDePasseTape);
				System.out.println("Bravo, le deuxième joueur est bien authentifié. Vous pouvez commencer à jouer.");	
				System.out.println("");
				System.out.println("");
				actionSuivante=Action.authentifierJoueur;
			}
		}
		else {
			System.out.println("Erreur d'identification. Veuillez recommencer la saisie.");
			actionSuivante=Action.menuConnexion;	        //si l'authentification n'est pas reussie l'utilisateur est renvoye au menu connexion
		}
		return actionSuivante;
	}



	/**
	 * METHODE QUI GERE LE MENU CHOIX TAILLE GRILLE
	 * cette méthode n'est pas utilisée pour l'instant car nous n'avons pas finalisé le jeu en réseau	 
	 * La méthode demande à l'utilisateur sur quelle taille de grille il veut bien jouer
	 * si la saisie de l'utilisateur n'est pas valable (taille de grille non permise, contenu autre que numérique...)
	 * la méthode en informe l'utilisateur et lui demande de taper à nouveau son choix
	 * au final la méthode renvoi le choix de l'utilisateur (listeChoix)  
	 * c'est une sous méthode : contientUniquementTaillesAutoriseesOuEspace  qui se charge de vérifier que
	 * le choix de l'utilisateur est valide 
	 * @return listeChoix : String qui contient toutes les tailles de grille sur lesquelles l'utilisateur veut jouer 
	 */

	public static String verifierChoixTailleGrilleDuJoueur(){
		String choixUtilisateur;
		String listeChoix="";
		boolean choixValide=false;

		System.out.println("Tapez toutes les tailles de grille (entre "+TAILLE_GRILLE_MIN+" et "+TAILLE_GRILLE_MAX+") pour lesquelles vous voulez jouer en les séparant d'un espace");
		System.out.println("(exemple :tapez 6 8 9 si vous voulez jouer sur une grille de taille 6, ou 8 ou 9) ou tapez G pour revenir au menu général.");
		while(!choixValide){
			Scanner sc=new Scanner(System.in);
			choixUtilisateur=(sc.nextLine()).toUpperCase();
			if ((choixUtilisateur).equals("G")){
				choixValide=true;			
			}
			else {
				choixValide=verifierSiContientUniquementTaillesAutoriseesOuEspace(choixUtilisateur);
				if (choixValide){

					listeChoix=choixUtilisateur;
				}
			}
			if (!choixValide){

				System.out.println("Entrez à nouveau votre choix.");
			}
		}
		return listeChoix;
	}


	/**
	 * Cette méthode vérifie que les choix de taille de grille tapées par l'utilisateur sont valides
	 * c'est à dire comprises entre TAILLE_GRILLE_MIN et TAILLE_GRILLE_MAX
	 * @return boolean : ce booléen est true si la chaine traitée ne contient que des tailles de grille autorisée, 
	 * 								et false sinon (si au moins une taille de grille n'est pas entre
	 * 								TAILLE_GRILLE_MIN et TAILLE_GRILLE_MAX
	 * 								ou si elle contient des valeurs non numériques
	 */

	public static boolean verifierSiContientUniquementTaillesAutoriseesOuEspace(String chaine){
		boolean chaineContientUniquementTaillesAutoriseesOuEspace, morceauInterdit, chaineInvalide;
		String chaineListeNombresAutorises=" ", kTransformeEnChaine="",morceauCourant;
		for (int k=TAILLE_GRILLE_MIN;k<TAILLE_GRILLE_MAX+1;k++)
		{
			kTransformeEnChaine=String.valueOf(k);
			chaineListeNombresAutorises=chaineListeNombresAutorises+kTransformeEnChaine+" "; 
			//chaineListeNombresAutorises contient tous les nombes autorises (exemple donne " 6 7 8 9 10 11 12 " si TAILLE_GRILLE_MIN et TAILLE_GRILLE_MAX sont respectivement égaux à 6 et 12
		}
		StringTokenizer morceauxDeChaineEntreDeuxEspaces;
		morceauxDeChaineEntreDeuxEspaces=new StringTokenizer (chaine," ");
		int nbMorceaux;
		nbMorceaux=morceauxDeChaineEntreDeuxEspaces.countTokens();

		chaineInvalide=false;
		for (int i=0 ; i<nbMorceaux ; i++)
		{ 
			morceauCourant=" "+morceauxDeChaineEntreDeuxEspaces.nextToken()+" ";
			morceauInterdit=(chaineListeNombresAutorises.indexOf(morceauCourant)==-1);
			chaineInvalide=(chaineInvalide||morceauInterdit);	
		}
		chaineContientUniquementTaillesAutoriseesOuEspace=!chaineInvalide;	

		return chaineContientUniquementTaillesAutoriseesOuEspace;
	}



	/**
	 * méthode qui demande à l'utilisateur sur quelle taille de grille il veut jouer, et qui boucle  
	 * tant que ce choix n'est pas compris (au sen large) entre TAILLE_GRILLE_MIN et TAILLE_GRILLE_MAX 
	 * @return tailleGrille : entier (compris entre TAILLE_GRILLE_MIN et TAILLE_GRILLE_MAX)
	 */

	public int obtenirLaTailleDeGrille(){
		boolean choixValide=false;
		int tailleGrille=0;
		System.out.println("Veuillez choisir une taille de grille (entier compris entre "+TAILLE_GRILLE_MIN+" et "+TAILLE_GRILLE_MAX+").");
		while(!choixValide){
			Scanner sc=new Scanner(System.in);
			String choixUtilisateur=(sc.nextLine()).toUpperCase();
			String kTransformeEnChaine;

			for (int k=TAILLE_GRILLE_MIN;k<TAILLE_GRILLE_MAX+1;k++)
			{
				kTransformeEnChaine = String.valueOf(k);
				choixValide=choixValide||(kTransformeEnChaine==choixUtilisateur);
				; //chaineListeNombresAutorises contient tous les nombes autorises (exemple donne " 6 7 8 9 10 11 12 " si TAILLE_GRILLE_MIN et TAILLE_GRILLE_MAX sont respectivement égaux à 6 et 12
			}					

			choixValide=verifierSiContientUniquementTaillesAutoriseesOuEspace(choixUtilisateur);
			if (choixValide){
				tailleGrille=Integer.valueOf(choixUtilisateur);
			}
			if (!choixValide){

				System.out.println("Entrez à nouveau votre choix.");
			}
		}
		return tailleGrille;
	}

	/**
	 * Méthode qui affiche les parties inachevées entre deux joueurs : user1 et user2
	 * pour chaque partie de la liste sont affichées : l'identifiant de la partie, l'identifiant du joueur1,
	 * l'identifiant du joueur2, le score du joueur1, le score du joueur2, la taille de la grille 
	 * et la date de début de la partie.
	 * D'autre part la méthode renvoi listeIdPartie qui est la liste des parties inachevées entre ces deux joueurs.
	 * @param user1 : Utilisateur identifiant de l'utilisateur1
	 * @param user2 : Utilisateur identifiant de l'utilisateur2
	 * @return listeIdPartie : liste des parties inachevées entre user1 et user2
	 */
	public List<Integer> afficherPartiesInachevees(Utilisateur user1, Utilisateur user2){
		DAO<Partie> dp1 = DAOFactory.getPartieDAO();
		List<Partie> listeParties = null;
		try {
			listeParties = dp1.getAll(user1.getNumUtilisateur(),user2.getNumUtilisateur());
		} catch (FonctionalException e) {

		} 
		if(listeParties.size()!=0){
			System.out.println("|"+gereEspaceTableau(10,"idPartie")+"|"+gereEspaceTableau(20,"Joueur 1")+
					"|"+gereEspaceTableau(20,"Joueur 2")+"|"+gereEspaceTableau(10,"Score 1")+
					"|"+gereEspaceTableau(10,"Score 2")+"|"+gereEspaceTableau(20,"Taille de la grille")+
					"|"+"Date de début"+"|");
			for (int i = 0; i < listeParties.size(); i++) {
				System.out.println("|"+gereEspaceTableau(10,listeParties.get(i).getNumPartie())+"|"
						+gereEspaceTableau(20,listeParties.get(i).getLesJoueurs().get(0).getIdentifiant())+"|"
						+gereEspaceTableau(20,listeParties.get(i).getLesJoueurs().get(1).getIdentifiant())+"|"
						+gereEspaceTableau(10,listeParties.get(i).getScoreJoueurUn())+"|"
						+gereEspaceTableau(10,listeParties.get(i).getScoreJoueurDeux())+"|"
						+gereEspaceTableau(20,listeParties.get(i).getTailleGrille())+"|"
						+listeParties.get(i).getDateDebut()+"   |");
			}}
		List<Integer> listeIdPartie=new ArrayList<Integer>();
		for (int i = 0; i < listeParties.size(); i++) {
			listeIdPartie.add(listeParties.get(i).getNumPartie());

		}
		return listeIdPartie;
	}



	/**
	 * méthode qui permet de demander à l'utilisateur d'entrer une case puis de la lire.
	 * Elle s'auto appele jusqu'a ce que l'utilisateur entre une case correct ou imterrope la partie ou passe son tour.
	 * @param  i  : correspond au moment où est appelée la méthode.
	 * i vaut 1 si c'est la première case appelée, on demande à l'utilisateur la case où il veut jouer.
	 * i vaut 2 lorsque l'on attend la case sur laquelle l'utilisateur souhaite déplacer le joker ou diable choisie précedement.
	 *@return la case choisie par l'utilisateur ou null si cellui-ci a imterropu la partie ou a passé son tour.
	 * */


	public static Case entrerCase(int i, Partie partieCourante){

		Case caseBut=null;
		//On initialise le scanner
		Scanner sc = new Scanner(System.in);

		//on affiche la bonne phrase
		if (i==2){
			System.out.println("Indiquez la case sur laquelle vous souhaitez déplacer le joker ou diable.");}
		else {
			if(partieCourante.isGrilleRemplie()){
				System.out.println("Choisissez la case sur laquelle vous souhaitez jouer (exemple : B5) ou tapez P pour Passer votre tour.");}
			else{
				System.out.println("Choisissez la case sur laquelle vous souhaitez jouer (exemple : B5) ou tapez I pour Interrompre la partie.");}}

		//On mémorise le choix de l'utilisateur
		String choix=sc.nextLine().toUpperCase();
		choix=choix.toUpperCase();

		if ((choix.equals("I")==false & partieCourante.isGrilleRemplie()==false) || (choix.equals("P")==false & partieCourante.isGrilleRemplie()) || i==2) {
			//Si l'utilisateur ne souhaite pas interrompre la partie ou passer sont tour lorsque le cas ce présente

			int y=-1;
			int x=-1;
			int tailleGrille=partieCourante.getTailleGrille();

			//on vérifie que la longueur de l'entrée est correcte

			if((choix.length()==2)||(choix.length()==3)){   
				//On recupere l'ordonnee de la case souhaitee
				char yChar = choix.charAt(0);
				y = (int)yChar - 65;
				//On recupere l'abscisse de la case souhaitée
				String xString = choix.substring(1);
				try{ 
					x = Integer.parseInt(xString)-1;
				}
				catch (java.lang.NumberFormatException exc){
					System.out.println("Saisie incorrecte. Veuillez recommencer.");
					caseBut=entrerCase(i, partieCourante);
					return caseBut;
				}
			}

			if (0>y||y>tailleGrille-1) {//On verifie que l'ordonnee correspond 
				//a la taille de la grille
				System.out.println("Saisie incorrecte. Veuillez recommencer.");
				caseBut=entrerCase(i, partieCourante);
				return caseBut;
			}
			else {
				if (0>x||x>tailleGrille-1) {//On verifie que l'abscisse correspond 
					//a  la taille de la grille
					System.out.println("Saisie incorrecte. Veuillez recommencer.");
					caseBut=entrerCase(i, partieCourante);
					return caseBut;
				}
				else {//Dans le cas ou tout est bon on renvoie la case choisie
					caseBut=partieCourante.getLaGrille()[x][y];
					return caseBut;
				}

			}
		}
		else {
			return caseBut;
		}
	}


	/**
	 * méthode qui permet de demander à l'utilisateur d'entrer un jeton puis de lire.
	 *  Elle boucle jusqu'a ce que l'utilisateur entre un jeton correct
	 * @return jetonAjouer qui est le jeton entré par l'utilisateur
	 */

	public static Jeton entrerJeton(Joueur joueurCourant){
		Jeton jetonAjouer=null;
		//Cette méthode bouclera jusqu'a ce que le joueur entre quelque chose de correcte
		Scanner sc01 = new Scanner(System.in);
		System.out.println("Choisissez le type de jeton à jouer (S, M, J ou D) et sa valeur " +
				"(entre 1 et 7) " +
				"(exemple : M5 pour jouer un jeton Multi affecté d'une valeur 5).");

		while (jetonAjouer==null){

			String jetonString = sc01.nextLine().toUpperCase();
			jetonString=jetonString.toUpperCase();
			if (!(jetonString.equals(""))){
				char carac = jetonString.charAt(0);
				//on prend le premier caractére entré par le joueur correspondant au type du jeton
				switch (carac)
				{
				case 'S':
					jetonAjouer=new Simple(joueurCourant.getCouleur());
					break;
				case 'D': 
					boolean diableTousUtiliser=true;
					int i=0;
					//sert a savoir si le joueur a utilisé tous ses jetons diables
					// les jetons diables, jokers puis multis sont créés 
					//dans cette ordre lors de l'initialisation de la partie

					while(diableTousUtiliser==true & i < Joueur.NBR_JETON_DIABLE){

						if (joueurCourant.getLesDiables().get(i).isDejaPose()==false){
							jetonAjouer=joueurCourant.getLesDiables().get(i);
							diableTousUtiliser=false;

						}
						i++;
					}

					if(diableTousUtiliser){
						System.out.println("Jeton indisponible. Veuillez recommencer.");
					}
					break;
				case 'J':
					boolean jokerTousUtiliser=true;
					int j=0;
					while(jokerTousUtiliser==true & j < Joueur.NBR_JETON_JOKER){

						if (joueurCourant.getLesJokers().get(j).isDejaPose()==false){
							jetonAjouer=joueurCourant.getLesJokers().get(j);
							jokerTousUtiliser=false;
						}
						j++;
					}

					if(jokerTousUtiliser){
						System.out.println("Jeton indisponible. Veuillez recommencer.");
					}
					break;


				case 'M':
					boolean multiTousUtiliser=true;
					int k=0;
					while(multiTousUtiliser==true & k < Joueur.NBR_JETON_MULTI){

						if (joueurCourant.getLesMultis().get(k).isDejaPose()==false){
							jetonAjouer=joueurCourant.getLesMultis().get(k);
							multiTousUtiliser=false;
						}
						k++;
					}

					if(multiTousUtiliser){
						System.out.println("Jeton indisponible. Veuillez recommencer.");
					}
					break;

				}


				if((jetonAjouer!=null) & (jetonString.length()==2)){
					char carac2 = jetonString.charAt(1);//on extrait le deuxiéme caractére qu'a rentré le joueur 
					switch (carac2)
					{
					case '1':
						jetonAjouer.setValeur(1);
						break;
					case '2':
						jetonAjouer.setValeur(2);
						break;
					case '3':
						jetonAjouer.setValeur(3);
						break;
					case '4':
						jetonAjouer.setValeur(4);
						break; 
					case '5':
						jetonAjouer.setValeur(5);
						break; 
					case '6':
						jetonAjouer.setValeur(6);
						break; 
					case '7':
						jetonAjouer.setValeur(7);
						break; 
					default:
						System.out.println("Saisie incorrecte. Veuillez recommencer.");

						jetonAjouer=null;
						break;

					}
				}
				else {
					System.out.println("Saisie incorrecte. Veuillez recommencer.");

					jetonAjouer=null;

				}
			}
			else{
				System.out.println("Saisie incorrecte. Veuillez recommencer.");
			}
		}
		return jetonAjouer;
	}

	/** méthode qui permet de récupérer la liste d'attente à partir de la base de données et de l'afficher
	 * @param u Utilisateur
	 * @return liste des utilisateurs présents dans la liste d'attente
	 * @throws FonctionalException
	 */
	public List<Utilisateur> afficherListeAttente(Utilisateur u) throws FonctionalException{
		DAO<Utilisateur> dU = DAOFactory.getUtilisateurDAO();
		List<Utilisateur> listeU=dU.obtenirListeAttente(u);
		if (listeU.size()!=0) {
			System.out.println("");
			System.out.println("------------------------------------------------------------------------");
			System.out.println("                             LISTE D'ATTENTE");
			System.out.println("------------------------------------------------------------------------");
			System.out.println("");

			System.out.println(gereEspaceTableau(20,"numéro du joueur")+"|"+gereEspaceTableau(20,"identifiant") +"|"+gereEspaceTableau(30,"tailles de grille proposées"));

			for (int i = 0; i < listeU.size(); i++) {

				System.out.println(gereEspaceTableau(20,i) +"|"+gereEspaceTableau(20, listeU.get(i).getIdentifiant())  +"|"+ gereEspaceTableau(30, listeU.get(i).getTaillesDeGrilleVoulues()));

			}
		}else{System.out.println("La liste d'attente est vide.");}

		return listeU;
	}

	/** méthode qui permet à l'utilisateur de choisir un adversaire présent dans liste d'attente.
	 * @param listeU liste des utilisateurs présents dans la liste d'attente
	 * @return utilisateur choisi
	 */
	public Utilisateur saisirNumeroJoueurSouhaite(List<Utilisateur> listeU){

		Utilisateur utilisateur=null;
		Scanner sc = new Scanner(System.in);
		boolean choixValide=false;

		while(!choixValide){
			System.out.println("Saisir le numero du joueur avec lequel vous souhaitez jouer ou tapez I pour Interrompre");
			String utilisateurString=sc.next().toUpperCase();
			if (utilisateurString.equals("I")) {
				choixValide=true;
			}else {
				try{ 
					int i=Integer.valueOf(utilisateurString);
					if(0<=i && i<listeU.size()){
						utilisateur=listeU.get(i);
						choixValide=true;
					}
				}catch (java.lang.NumberFormatException exc){
					System.out.println("Saisie invalide.");
					choixValide=false;
				}
			}
		}

		return utilisateur;
	}




	/**méthode qui sérialise un utilisateur
	 * @param utilisateurASerialiser
	 * @return le string représentant l'utilisateur
	 */
	public String serializer(Utilisateur utilisateurASerialiser){

		String sortie;

		sortie=""+utilisateurASerialiser.getNumUtilisateur()+ControleurPartieReseau.SEPARATEUR+
				utilisateurASerialiser.getIdentifiant()+ControleurPartieReseau.SEPARATEUR
				+utilisateurASerialiser.getMotDePasse()+ControleurPartieReseau.SEPARATEUR+
				utilisateurASerialiser.getAdresseIp();

		return sortie;
	}



	/** méthode qui déserialise une chaîne de caractère en un utilisateur
	 * @param chaine
	 * @return l'utilisateur
	 */
	public Utilisateur deserializer(String chaine){
		Utilisateur u=null;
		StringTokenizer st=new StringTokenizer(chaine, ControleurPartieReseau.SEPARATEUR);
		int numUtilisateur=Integer.valueOf(st.nextToken());
		String identifiant=st.nextToken();
		String motDePasse=st.nextToken();
		String ip=st.nextToken();
		u=new Utilisateur(numUtilisateur, identifiant, motDePasse, null,ip);

		return u;
	}



	/** 
	 * méthode permettant à l'utilisateur de choisir le niveau de difficulté de l'IA.
	 */
	public void choisirNiveauDeDifficulteIA(){
		menuChoixDuNiveauDeJeu.afficheMenu(); 
		Action choixNiveauIA = menuChoixDuNiveauDeJeu.obtenirChoixUtilisateur();

		switch  (choixNiveauIA){
		case niveau0:
			utilisateur2=new Utilisateur(1, "IA0", "aaaa");
			break;

		case niveau1:
			utilisateur2=new Utilisateur(2, "IA1", "aaaa");
			break;

		case niveau2:
			utilisateur2=new Utilisateur(3, "IA2", "aaaa");
			break;
		}
	}

	/**
	 * méthode permettant à l'utilisateur de choisir de reprendre une ancienne partie ou d'en créer une nouvelle.
	 */
	public void choisirNouvelleOuReprendrePartie(){

		boolean partieChoisie=false;
		while(!partieChoisie){
			//l'utilisateur choisi de jouer une Nouvelle partie, ou de reprendre une ancienne partie
			menuChoixDuTypeDePartie.afficheMenu(); 
			Action typeDePartie=menuChoixDuTypeDePartie.obtenirChoixUtilisateur();


			if (typeDePartie==Action.debuterUneNouvellePartie){ //cas où l'utilisateur choisi de jouer une nouvelle partie
				int tailleGrille=0;
				tailleGrille=obtenirLaTailleDeGrille();   //methode qui permet de recuper la taille de grille tapée par l'utilisateur
				try {
					partieChoisie=true;
					new ControleurPartie(0,tailleGrille,utilisateur1,utilisateur2);//On cree une partie
				} catch (FonctionalException e) {
					System.out.println("La partie a été interrompue par une erreur.");
				}

			}


			if (typeDePartie==Action.reprendreUneAnciennePartie){ //cas où l'utilisateur choisi de jouer une ancienne partie
				List<Integer> listeIdPartie=afficherPartiesInachevees(utilisateur1, utilisateur2);
				if(listeIdPartie.size()!=0){
					System.out.println("");
					System.out.println("Veuillez indiquer l'identifiant de la partie à charger.");
					Scanner scIdPartie=new Scanner(System.in);

					int p=-1;

					String choixIdPartie=scIdPartie.nextLine();
					try{
						p=Integer.valueOf(choixIdPartie);

						for (int i = 0; i < listeIdPartie.size(); i++) {
							if (p==listeIdPartie.get(i).intValue()) {

								try {
									partieChoisie=true;
									new ControleurPartie(p,0,utilisateur1,utilisateur2);
								} catch (FonctionalException e) {
									System.out.println("La partie a été interrompue par une erreur.");
								}
							}
						}
					}
					catch (java.lang.NumberFormatException exc){
						System.out.println("Saisie invalide.");
					}
				}

				else{
					System.out.println("La liste des anciennes parties est vide.");
				}
			}}}

	/** méthode permettant à l'utilisateur de s'inscrire sur la liste d'attente. L'utilisateur est alors bloqué jusqu'à ce qu'un autre utilisateur
	 * décide de jouer avec ce dernier.
	 */
	public void inscrireListeAttente(){
		try{
			DAO<Utilisateur> dU=DAOFactory.getUtilisateurDAO();
			utilisateur1.setAdresseIp();
			String choix=verifierChoixTailleGrilleDuJoueur();
			utilisateur1.setTaillesDeGrilleVoulues(choix);

			dU.sinscrireSurListeAttente(utilisateur1);
			ServerSocket s = new ServerSocket(8080);
			System.out.println("Veuillez patienter, un autre joueur peut vous rejoindre.");
			Socket soc = s.accept();

			// Un BufferedReader permet de lire par ligne.
			BufferedReader plec = new BufferedReader(new InputStreamReader(soc.getInputStream()));
			String stringUtilisateur=plec.readLine();
			int tailleGrille=Integer.valueOf(plec.readLine());
			s.close();
			Utilisateur adversaire=deserializer(stringUtilisateur);
			desinscrireListeAttente();
			System.out.println("La partie commence. Vous allez affronter le joueur " + adversaire.getIdentifiant() );
			new ControleurPartieReseau(0,tailleGrille , utilisateur1, adversaire, adversaire.getAdresseIp(),1);

		}catch (UnknownHostException e) {
			System.out.println("Une erreur est survenue lors de la communication avec l'ordinateur distant.");
			actionEnCours=Action.menuGeneral;
		} catch (FonctionalException e) {
			actionEnCours=Action.menuGeneral;
		} catch (IOException e) {
			System.out.println("Une erreur est survenue lors de la communication avec l'ordinateur distant.");
			actionEnCours=Action.menuGeneral;
		}	
	}

	/** méthode permettant à l'utilisateur de lancer une partie contre un adversaire choisie dans la liste. Cette méthode appelle la 
	 *  méthode saisirNumeroJoueurSouhaite(listeAttente).
	 */
	public void choisirAdversaire(){
		Utilisateur utilisateurChoisie=saisirNumeroJoueurSouhaite(listeAttente);
		if (utilisateurChoisie==null) {
			actionEnCours=Action.menuGeneral;
		} else {

			String stringIp=utilisateurChoisie.getAdresseIp();
			int n=obtenirLaTailleDeGrille();
			try {
				utilisateur1.setAdresseIp();
				Socket socket = new Socket(stringIp, 8080);
				PrintWriter pred = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
				pred.println(serializer(utilisateur1));
				pred.println(n);
				socket.close();
				desinscrireListeAttente();
				new ControleurPartieReseau(0, n,utilisateurChoisie , utilisateur1, stringIp,2);


			} catch (FonctionalException e) {
				actionEnCours=Action.menuGeneral;
			}
			catch (UnknownHostException e3) {
				System.out.println("Une erreur est survenue lors de la communication avec l'ordinateur distant.");
				actionEnCours=Action.menuGeneral;
			} catch (IOException e3) {
				System.out.println("Une erreur est survenue lors de la communication avec l'ordinateur distant.");
				actionEnCours=Action.menuGeneral;
			}

			actionEnCours=Action.menuGeneral;

		}

	}

	/** méthode permettant de gérer le menu connexion du joueur2
	 * @throws FonctionalException
	 * @throws TechnicalException
	 */
	public void gererMenuConnexionJoueur2() throws FonctionalException, TechnicalException{

		boolean faireActionSuivante=false;
		while (!faireActionSuivante){
			System.out.println();
			System.out.println("C'est maintenant au deuxième joueur de s'authentifier, ou de créer un compte.");
			System.out.println();
			System.out.println();
			menuConnexion.afficheMenu();
			actionSuivante=menuConnexion.obtenirChoixUtilisateur();


			switch(actionSuivante){
			case authentifierJoueur :		//on lance l'authentification du deuxieme joueur		
				actionEnCours=authentifierJoueur(2);
				faireActionSuivante=(actionEnCours==Action.authentifierJoueur);
				break;

			case afficherReglesJeuMenuInscription :		
				gererInscription(2);              //execution du menu incription		
				faireActionSuivante=true;
				break;

			case quitterProgramme :
				actionEnCours=Action.quitterProgramme;	
				faireActionSuivante=true;
				break;

			}

		}
	}


	/** méthode permettant de gérer l'affichage des colonnes, celle-ci veille à ce que les colonnes soient de largeur constante.
	 * @param i largeur de la colone souhaitée.
	 * @param sansEspace chaine de caractère à insérer dans une colonne.
	 * @return
	 */
	public <T> String gereEspaceTableau(int i, T sansEspace){

		String avecEspace=null;
		int k=i-(""+sansEspace).length();
		if(k>=0){

			avecEspace=""+sansEspace;

			for(int m=0; m<k; m++){
				avecEspace=avecEspace+" ";
			}
		}
		else{
			avecEspace="pp";

		}
		return avecEspace;	
	}




	/**méthode permettant à un utilisateur de se désincrire de la liste d'attente au moment où celui-ci commence
	 * une partie en réseau.
	 */
	public void desinscrireListeAttente(){
		DAO<Utilisateur> dU=DAOFactory.getUtilisateurDAO();
		try {
			dU.desinscrireListeAttente(utilisateur1);
		} catch (FonctionalException e) {

		}

	}


}
